use crate::{
    models::personnel::PosPersonnel,
    reply::{Code, Reply},
    state::State,
};
use entity::{
    personnel, position,
    prelude::{Personnel, Position},
};
use poem::{
    handler,
    web::{Data, Json, Path},
};
use sea_orm::{
    ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, QuerySelect,
};

/*
 * #[handler]
 * pub async fn batch(
 *     Data(State { db, ..}): Data<&State>,
 * ) -> Reply<Vec<position::Model>> {
 *     let positions = Position::find().all(db).await.unwrap();
 *     Reply::new().data(positions)
 * }
 */

#[handler]
pub async fn personnels(
    Data(State { db, .. }): Data<&State>,
    Path(id): Path<i32>,
) -> Reply<Vec<PosPersonnel>> {
    let personnels = Personnel::find()
        .select_only()
        .column(personnel::Column::Id)
        .column(personnel::Column::Name)
        .column(personnel::Column::Sex)
        .filter(personnel::Column::PositionId.eq(id))
        .filter(personnel::Column::IsEmployed.eq(true))
        .into_model::<PosPersonnel>()
        .all(db)
        .await
        .unwrap();

    Reply::new().data(personnels)
}

#[handler]
pub async fn create(
    Data(State { db, .. }): Data<&State>,
    Json(position): Json<position::InsertModel>,
) -> Reply {
    let name = position.name.clone();
    let position = position.into_active_model();
    let mut reply = Reply::new();

    if position.insert(db).await.is_err() {
        reply.set_code(Code::DuplicateItem).set_msg(name);
    }

    reply
}

#[handler]
pub async fn update(
    Data(State { db, .. }): Data<&State>,
    Json(position): Json<position::UpdateModel>,
) -> Reply {
    let name = position.name.clone();
    let position = position.into_active_model();
    let mut reply = Reply::new();

    if position.update(db).await.is_err() {
        reply.set_code(Code::DuplicateItem).set_msg(name);
    }

    reply
}

#[handler]
pub async fn delete(Data(State { db, .. }): Data<&State>, Path(id): Path<i32>) -> Reply {
    let _ = Position::delete_by_id(id).exec(db).await;

    Reply::new()
}
